package river_city_ransom.tests;

import java.util.ArrayList;
import java.util.List;

import river_city_ransom.contracts.Bloc_C;
import river_city_ransom.contracts.Dimensions_C;
import river_city_ransom.contracts.Objet_C;
import river_city_ransom.contracts.Position_C;
import river_city_ransom.contracts.Terrain_C;
import river_city_ransom.implementations.Bloc_I;
import river_city_ransom.implementations.Dimensions_I;
import river_city_ransom.implementations.Objet_I;
import river_city_ransom.implementations.Position_I;
import river_city_ransom.implementations.Terrain_I;
import river_city_ransom.services.Bloc;
import river_city_ransom.services.Dimensions;
import river_city_ransom.services.Objet;
import river_city_ransom.services.Position;
import river_city_ransom.services.Terrain;
import river_city_ransom.types.BlocType;
import river_city_ransom.types.ObjetNom;
import tools.Toolbox;
import exceptions.ComposantError;
import junit.framework.TestCase;


public class Terrain_T extends TestCase {
	public void test_init_ok() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			assertTrue(Toolbox.equals(t.dimensions(), d));
			assertTrue(Toolbox.equals(t.blocs(), lb));
			assertTrue(Toolbox.equals(t.objets(), lo));
		}
		catch(ComposantError e) {
			System.err.println("Terrain::test_init_ok\n\t" + e.getMessage());
			fail(e.getMessage());
		}
	}

	public void test_init_ko_1() {
		try {
			int l = 50, p = 30;
			Dimensions d = null;
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			System.err.println("Terrain::test_init_ko_1\n\tException non levée.");
			fail("Exception non lev�e.");
		}
		catch(ComposantError e) {
		}
	}

	public void test_init_ko_2() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			System.err.println("Terrain::test_init_ko_2\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}

	public void test_init_ko_3() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			List<Objet> lo = new ArrayList<Objet>();
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			System.err.println("Terrain::test_init_ko_3\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}
	
	public void test_setBloc_ok() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			int x = 10, y = 10, z = 20;
			Position p1 = new Position_C(new Position_I(x, y, z));
			Bloc b1 = new Bloc_C(new Bloc_I(BlocType.VIDE, p1));
			List<Bloc> lb_pre = new ArrayList<Bloc>(t.blocs());
			t.setBloc(b1);
			assertTrue(Toolbox.equals(t.bloc(p1), b1));
			lb_pre.add(b1);
			assertTrue(Toolbox.equals(t.blocs(), lb_pre));
		}
		catch(ComposantError e) {
			System.err.println("Terrain::test_setBloc_ok\n\t" + e.getMessage());
			fail(e.getMessage());
		}
	}
	
	public void test_setBloc_ko() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			int x = 10, y = 10, z = 0;
			Position p1 = new Position_C(new Position_I(x, y, z));
			Bloc b1 = new Bloc_C(new Bloc_I(BlocType.VIDE, p1));
			t.setBloc(b1);
			System.err.println("Terrain::test_setBloc_ko\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}
	
	public void test_delBloc_ok() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			int x = 10, y = 10, z = 0;
			Position p1 = new Position_C(new Position_I(x, y, z));
			Bloc b1 = new Bloc_C(new Bloc_I(BlocType.VIDE, p1));
			List<Bloc> lb_pre = new ArrayList<Bloc>(t.blocs());
			t.delBloc(b1);
			assertTrue(Toolbox.equals(t.bloc(p1), null));
			lb_pre.remove(b1);
			assertTrue(Toolbox.equals(t.blocs(), lb_pre));
		}
		catch(ComposantError e) {
			System.err.println("Terrain::test_delBloc_ok\n\t" + e.getMessage());
			fail(e.getMessage());
		}
	}
	
	public void test_delBloc_ko() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			int x = 10, y = 10, z = 20;
			Position p1 = new Position_C(new Position_I(x, y, z));
			Bloc b1 = new Bloc_C(new Bloc_I(BlocType.VIDE, p1));
			t.delBloc(b1);
			System.err.println("Terrain::test_delBloc_ko\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}

	public void test_addObjet_ok() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o1 = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o1.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o1);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			Objet o2 = new Objet_C(new Objet_I(ObjetNom.POUBELLE_METALLIQUE));
			o2.deplacer(new Position_C(new Position_I(16, 1, 15)));
			List<Objet> lo_pre = new ArrayList<Objet>(t.objets());
			t.addObjet(o2);
			lo_pre.add(o2);
			assertTrue(Toolbox.equals(t.objets(), lo_pre));
		}
		catch(ComposantError e) {
			System.err.println("Terrain::test_addObjet_ok\n\t" + e.getMessage());
			fail(e.getMessage());
		}
	}

	public void test_addObjet_ko() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o1 = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o1.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o1);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			Objet o2 = null;
			List<Objet> lo_pre = new ArrayList<Objet>(t.objets());
			t.addObjet(o2);
			lo_pre.add(o2);
			System.err.println("Terrain::test_addObjet_ko\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}

	public void test_delObjet_ok() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			List<Objet> lo_pre = new ArrayList<Objet>(t.objets());
			t.delObjet(o);
			lo_pre.remove(o);
			assertTrue(Toolbox.equals(t.objets(), lo_pre));
		}
		catch(ComposantError e) {
			System.err.println("Terrain::test_delObjet_ok\n\t" + e.getMessage());
			fail(e.getMessage());
		}
	}

	public void test_delObjet_ko() {
		try {
			int l = 50, h = 50, p = 30;
			Dimensions d = new Dimensions_C(new Dimensions_I(l, h, p));
			List<Bloc> lb = new ArrayList<Bloc>();
			Objet o1 = new Objet_C(new Objet_I(ObjetNom.CHAINE_DE_VELO));
			o1.deplacer(new Position_C(new Position_I(1, 1, 1)));
			List<Objet> lo = new ArrayList<Objet>();
			lo.add(o1);
			for(int x_tmp = 0; x_tmp < l - 1; x_tmp++) {
				for(int y_tmp = 0; y_tmp < p - 1; y_tmp++) {
					Position p_tmp = new Position_C(new Position_I(x_tmp, y_tmp, 0));
					Bloc b_tmp = new Bloc_C(new Bloc_I(BlocType.VIDE, p_tmp));
					lb.add(b_tmp);
				}
			}
			Terrain t = new Terrain_C(new Terrain_I(d, lb, lo));
			t.init(d, lb, lo);
			Objet o2 = new Objet_C(new Objet_I(ObjetNom.POUBELLE_METALLIQUE));
			o2.deplacer(new Position_C(new Position_I(16, 1, 15)));
			t.delObjet(o2);
			System.err.println("Terrain::test_delObjet_ko\n\tException non levée.");
			fail("Exception non levée.");
		}
		catch(ComposantError e) {
		}
	}
}
